<template>
  <div class="aprd-container">
    <!-- 搜索区域 -->
    <div class="aprd-search-container">
      <el-form :inline="true" :model="searchParams" class="aprd-search-form">
        <el-form-item label="开始时间">
          <el-date-picker v-model="searchParams.startTime" type="datetime" placeholder="选择日期时间"
            format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" size="small" />
        </el-form-item>
        <el-form-item label="结束时间">
          <el-date-picker v-model="searchParams.endTime" type="datetime" placeholder="选择日期时间"
            format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" size="small" />
        </el-form-item>
        <el-form-item label="出口卷号">
          <el-input v-model="searchParams.exitCoilNo" placeholder="请输入出口卷号" size="small" clearable></el-input>
        </el-form-item>
        <el-form-item label="宽度分档">
          <el-input v-model="searchParams.widthBin" placeholder="请输入" size="small" clearable>
          </el-input>
        </el-form-item>
        <el-form-item label="出口厚度分档">
          <el-input v-model="searchParams.exitThicknessBin" placeholder="请输入" size="small" clearable>
          </el-input>
        </el-form-item>
        <el-form-item label="钢种分档">
          <el-input v-model="searchParams.steelGradeBin" placeholder="请输入" size="small" clearable>
          </el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch" size="small">查询</el-button>
          <el-button @click="handleReset" size="small">重置</el-button>
          <el-button type="success" @click="handleExport" size="small">导出</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 数据表格 -->
    <div class="aprd-table-container">
      <el-table :data="tableData" border style="width: 100%" :header-cell-style="headerStyle" height="100%">
        <el-table-column prop="seqNo" label="序号" width="60" fixed="left" align="center" />
        <!-- 动态基础字段 -->
        <el-table-column v-for="key in baseTableFields" :key="key" :prop="key" :label="getFieldLabel(key)"
          align="center"
          :width="key === 'entid' ? 150 : key === 'extid' ? 150 : key === 'createTime' ? 180 : undefined">
          <template #default="scope">
            <span v-if="isTimeField(key)">{{ formatDate(scope.row[key]) }}</span>
            <span v-else>{{ (scope.row[key] !== undefined && scope.row[key] !== '') ? scope.row[key] : '-' }}</span>
          </template>
        </el-table-column>
        <!-- 多级表头：CPC相关字段分组 -->
        <el-table-column label="纠偏缸均值" align="center">
          <el-table-column v-for="key in cpcAvgFields" :key="key" :prop="key" :label="getFieldLabel(key)"
            align="center">
            <template #default="scope">
              <span>{{ (scope.row[key] !== undefined && scope.row[key] !== null && scope.row[key] !== '') ?
                scope.row[key] :
                '-' }}</span>
            </template>
          </el-table-column>
        </el-table-column>
        <el-table-column label="带钢均值" align="center">
          <el-table-column v-for="key in cpcStripAvgFields" :key="key" :prop="key" :label="getFieldLabel(key)"
            align="center">
            <template #default="scope">
              <span>{{ (scope.row[key] !== undefined && scope.row[key] !== null && scope.row[key] !== '') ?
                scope.row[key] :
                '-' }}</span>
            </template>
          </el-table-column>
        </el-table-column>
        <el-table-column label="带钢最大值" align="center">
          <el-table-column v-for="key in cpcStripMaxFields" :key="key" :prop="key" :label="getFieldLabel(key)"
            align="center">
            <template #default="scope">
              <span>{{ (scope.row[key] !== undefined && scope.row[key] !== null && scope.row[key] !== '') ?
                scope.row[key] :
                '-' }}</span>
            </template>
          </el-table-column>
        </el-table-column>
        <el-table-column prop="entid" label="入口卷号" width="150" align="center">
          <template #default="scope">
            <span>{{ scope.row.entid !== undefined && scope.row.entid !== null && scope.row.entid !== '' ?
              scope.row.entid : '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="extid" label="出口卷号" width="150" align="center">
          <template #default="scope">
            <span>{{ scope.row.extid !== undefined && scope.row.extid !== null && scope.row.extid !== '' ?
              scope.row.extid : '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="生产时间" width="180" align="center">
          <template #default="scope">
            <span>{{ formatDate(scope.row.createTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="详情" width="80" fixed="right" align="center">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="showDetail(scope.row)">详情</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="aprd-pagination">
        <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
          :page-sizes="[10, 20, 30, 50, 100]" background layout="total, sizes, prev, pager, next, jumper"
          :total="totalItems" @size-change="handleSizeChange" @current-change="handleCurrentChange" size="small" />
      </div>
    </div>

    <!-- 详情弹窗 -->
    <el-dialog v-model="detailDialogVisible" title="跑偏详细信息" width="90%" top="5vh" class="aprd-detail-dialog"
      destroy-on-close @closed="handleDialogClose" @opened="handleDialogOpened">
      <div class="aprd-detail-container">
        <!-- 顶部信息 -->
        <div class="aprd-detail-info">
          <el-descriptions :column="9" border size="small">
            <el-descriptions-item v-for="key in baseDetailFields" :key="key" :label="getFieldLabel(key)">
              <template #default>
                <span v-if="isTimeField(key)">{{ formatDate(detailData[key]) }}</span>
                <span v-else>{{ (detailData[key] !== undefined && detailData[key] !== '') ? detailData[key] : '-'
                }}</span>
              </template>
            </el-descriptions-item>
          </el-descriptions>
        </div>
        <!-- 图表区域 -->
        <div class="aprd-detail-charts-area">
          <!-- 左侧 CPC 图表区 多列紧凑排列 -->
          <div class="aprd-cpc-charts-list">
            <div v-for="(item, index) in detailData.cpcData" :key="item.name" class="aprd-cpc-chart-item">
              <div class="aprd-cpc-chart-title">{{ item.name }}</div>
              <div class="aprd-cpc-chart" :ref="el => cpcChartRefs[index] = el"></div>
            </div>
          </div>
          <div class="aprd-analysis-charts">
            <!-- 跑偏原因智能分析 -->
            <div class="aprd-analysis-section aprd-chart-item">
              <div class="aprd-chart-title">跑偏原因智能分析</div>
              <div class="aprd-analysis-content">
                <div class="analysis-item">
                  <span>是否特殊钢种:</span>
                  <el-tag :type="detailData.isSpecialSteel ? 'warning' : 'success'" size="small">{{
                    detailData.isSpecialSteel ? '是' : '否' }}</el-tag>
                </div>
                <div class="analysis-item">品规历史跑偏风险: {{ detailData.historyRisk }}%</div>
                <div class="analysis-item">热轧来料情况: {{ detailData.hotRollCondition }}</div>
                <div class="analysis-item">凸度命中率: {{ detailData.c40Passrate }}%</div>
                <div class="analysis-item">楔形命中率: {{ detailData.w40Passrate }}%</div>
              </div>
            </div>

            <!-- 凸度/楔形图表 -->
            <div class="aprd-chart-item">
              <div class="aprd-chart-title">凸度曲线-C40 / 楔形曲线-W40 (μm)</div>
              <div class="aprd-chart" ref="convexityWedgeChartRef"></div>
            </div>

            <!-- 生产过程追溯图表 -->
            <div class="aprd-chart-item">
              <div class="aprd-chart-title">生产过程追溯</div>
              <div class="aprd-chart" ref="processTraceChartRef"></div>
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="detailDialogVisible = false" size="small">关闭</el-button>
        </span>
      </template>
    </el-dialog>

  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
import * as echarts from 'echarts/core'
import {
  LineChart,
} from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  MarkLineComponent,
  ToolboxComponent, // Added for potential chart tools
  DataZoomComponent // Added for potential zooming
} from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
import type { EChartsOption } from 'echarts'
import { ActualPerformanceRollDeviationApi } from '/@/api/deviationanalysis/ActualPerformanceRollDeviation'

// Register ECharts components
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  MarkLineComponent,
  ToolboxComponent,
  DataZoomComponent,
  LineChart,
  CanvasRenderer
])

// API 接口
// import { ActualPerformanceRollDeviationApi } from '/@/api/deviationanalysis/ActualPerformanceRollDeviation'; // 假设已定义

// 帮助函数：转换日期时间格式
const formatDateTimeForApi = (dateTimeStr: string | null | undefined): string | undefined => {
  if (!dateTimeStr) return undefined;
  // Input: "YYYY-MM-DD HH:mm:ss"
  // Output: "YYYY-MM-DD-HH.mm.ss.000000" (assuming 0 microseconds if not available)
  return dateTimeStr.replace(' ', '-') + '.000000';
};

// 搜索参数
const searchParams = reactive({
  startTime: '2025-04-01 14:31:47', // 默认值或从其他地方获取
  endTime: '2025-04-30 14:31:47',   // 默认值或从其他地方获取
  parentCoilNo: '', // -> matIdent
  exitCoilNo: '',   // -> extid
  widthBin: '',     // -> widthCode
  exitThicknessBin: '', // -> thickCode
  steelGradeBin: '',  // -> gradeCode
})

// 分页相关
const currentPage = ref(1)
const pageSize = ref(30)
const totalItems = ref(0) // 初始化为0，从API获取

// 表头样式
const headerStyle = {
  background: '#eef1f6',
  color: '#606266'
}

// 表格数据 (将由API填充)
const tableData = reactive<any[]>([])

// 详情弹窗
const detailDialogVisible = ref(false)
const detailData = reactive({ // Structure for detail data based on API response + existing fields
  extid: '',    // 出口卷号 (from exitCoilNo)
  steelGrade: '',
  width: null as number | null,         // 出口宽度 (from exitWidth)
  thick: null as number | null,         // 出口厚度 (from exitThickness)
  length: null as number | null,
  paopianRate: null as number | null,   // 预测跑偏概率 (from deviationProb)
  paopianFlagTrue: null as number | null, // 是否跑偏 (from stripDeviation mapped to paopianFlagTrue)
  createTime: '', // 创建时间 (from time)
  shiftNo: null as number | null,       // 班次 (from shift)
  gradeCode: null as number | null,     // 钢种分档 (from steelGradeBin)
  widthCode: null as number | null,     // 宽度分档 (from widthBin)
  thickCode: null as number | null,     // 出口厚度分档 (from exitThicknessBin)

  // Fields from API to add to detail view
  entryThick: null as number | null,
  entryWidth: null as number | null,
  entryLength: null as number | null, // Assuming entryLength is also needed if entryThick/Width are
  hotCoilId: '',
  paopianFlag: null as number | null, //纠偏满载

  // Analysis section fields - map from API or keep mock if necessary
  isSpecialSteel: false, // Keep mock or remove if not derivable
  historyRisk: 0,      // Keep mock or remove
  hotRollCondition: '良好', // Keep mock or remove
  c40Passrate: null as number | string | null,     // 凸度命中率 (from convexityRate)
  w40Passrate: null as number | string | null,     // 楔形命中率 (from wedgeRate)

  // Chart data arrays (mock generation logic remains for now)
  cpcData: [] as { x: number[]; ds: number[]; os: number[] }[],
  convexityWedgeData: { x: [] as number[], c40: [] as number[], w40: [] as number[], upper: [] as number[], lower: [] as number[] },
  processTraceData: { x: [] as number[], tensionDiff1: [] as number[], tensionDiff2: [] as number[], speed: [] as number[] },
  // 索引签名，允许通过字符串索引访问所有字段

} as Record<string, any>);

// Chart Refs
const cpcChartRefs = ref<any[]>([]);
const convexityWedgeChartRef = ref<HTMLElement | null>(null);
const processTraceChartRef = ref<HTMLElement | null>(null);

// Chart Instances
let cpcChartInstances: (echarts.ECharts | null)[] = [];
let convexityWedgeChartInstance: echarts.ECharts | null = null;
let processTraceChartInstance: echarts.ECharts | null = null;
let cpcBigChartInstance: echarts.ECharts | null = null;

// --- 事件处理函数 ---
const handleSearch = async () => {
  // ElMessage.success('执行查询'); // Replaced by API call
  console.log('查询参数:', searchParams)
  const payload = {
    page: {
      pageIndex: currentPage.value,
      pageSize: pageSize.value
    },
    dto: {
      extid: searchParams.exitCoilNo || undefined,
      matIdent: searchParams.parentCoilNo || undefined,
      gradeCode: searchParams.steelGradeBin ? Number(searchParams.steelGradeBin) : undefined,
      startTime: formatDateTimeForApi(searchParams.startTime),
      endTime: formatDateTimeForApi(searchParams.endTime),
      thickCode: searchParams.exitThicknessBin ? Number(searchParams.exitThicknessBin) : undefined,
      widthCode: searchParams.widthBin ? Number(searchParams.widthBin) : undefined,
    }
  };
  // Remove undefined keys from dto to avoid sending empty parameters
  Object.keys(payload.dto).forEach(key => {
    if (payload.dto[key as keyof typeof payload.dto] === undefined) {
      delete payload.dto[key as keyof typeof payload.dto];
    }
  });

  try {
    const apiResponse = await ActualPerformanceRollDeviationApi.findByPage(payload);
    console.log("回调参数", apiResponse)

    // Assuming apiResponse is the full AxiosResponse, so data is in apiResponse.data
    // And the actual records and total are in response.data.data according to the new log
    if (apiResponse && apiResponse.data && apiResponse.data.data && Array.isArray(apiResponse.data.data.records)) {
      const responsePayload = apiResponse.data; // Outer payload with msg, status, nested data
      const actualData = responsePayload.data; // Nested data with records, total, etc.

      tableData.splice(0, tableData.length);

      actualData.records.forEach((record: any, index: number) => {
        const newRow: any = {
          seqNo: (currentPage.value - 1) * pageSize.value + index + 1,
          // Map fields from record (camelCase from API) to tableData fields
          exitCoilNo: record.extid,
          parentCoilNo: record.matIdent,
          steelGrade: record.steelGrade,
          exitWidth: record.width,
          exitThickness: record.thick,
          length: record.length,
          deviationProb: record.paopianRate,
          stripDeviation: record.paopianFlagTrue, // paopianFlagTrue seems to be the 'is deviation' flag
          time: record.createTime ? new Date(record.createTime).toLocaleString() : '-', // Format timestamp
          shift: record.shiftNo,
          steelGradeBin: record.gradeCode,
          widthBin: record.widthCode,
          exitThicknessBin: record.thickCode,
          // Keep the rest of the record data for the detail view
          ...record
        };
        // Map cpcXStripMax/Avg correctly
        for (let i = 1; i <= 10; i++) {
          // Use optional chaining and nullish coalescing for safety
          newRow['max_strip' + i] = record?.[`cpc${i}StripMax`] ?? null;
          newRow['avg_strip' + i] = record?.[`cpc${i}StripAvg`] ?? null;
        }
        tableData.push(newRow);
      });
      // Use total from the nested data object
      totalItems.value = actualData.total || 0;
      // Use msg from the outer responsePayload object
      ElMessage.success(responsePayload.msg || '查询成功');
    } else {
      // Handle cases where apiResponse.data.data or apiResponse.data.data.records might be missing
      const errorMessage = apiResponse?.data?.msg || '查询失败，数据结构不正确或无记录';
      ElMessage.error(errorMessage);
      tableData.splice(0, tableData.length);
      totalItems.value = 0;
    }
  } catch (error: any) {
    console.error('API call failed:', error);
    // Attempt to get a message from error.response.data.msg if it's an API error
    const anError = error as any;
    const apiErrorMessage = anError.response && anError.response.data && anError.response.data.msg
      ? anError.response.data.msg
      : (anError.msg || anError.message || '查询接口调用失败');
    ElMessage.error(apiErrorMessage);
    tableData.splice(0, tableData.length);
    totalItems.value = 0;
  }
}

const handleReset = () => {
  searchParams.startTime = '2025-03-30 14:31:47'; // Reset to defaults or clear
  searchParams.endTime = '2025-03-31 14:31:47';
  searchParams.parentCoilNo = '';
  searchParams.exitCoilNo = '';
  searchParams.widthBin = '';
  searchParams.exitThicknessBin = '';
  searchParams.steelGradeBin = '';
  currentPage.value = 1;
  handleSearch(); // Optionally re-fetch data with default/empty params
  ElMessage.info('重置搜索条件');
}
const handleExport = () => { ElMessage.success('执行导出') } // TODO: Implement export logic
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  currentPage.value = 1; // Reset to first page when size changes
  handleSearch();
  console.log(`每页 ${val} 条`)
}
const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  handleSearch();
  console.log(`当前页: ${val}`)
}

const cpcChartNames = [
  'CPC1', 'CPC2', 'CPC3', 'CPC4', 'CPC5', 'CPC6', 'CPC7', 'CPC8',
  'CPC9-0', 'CPC9-1', 'CPC9-2', 'CPC9-3', 'CPC9-4', 'CPC9-5', 'CPC9-6', 'CPC9-7', 'CPC9-8',
  'CPC10', 'CPC11', 'CPC12', 'CPC13', 'CPC14', 'CPC15', 'CPC16', 'CPC17',
  'EPC1', 'EPC2'
];
const cpcDataKeys = [
  'cal_cpc1', 'cal_cpc2', 'cal_cpc3', 'cal_cpc4', 'cal_cpc5', 'cal_cpc6', 'cal_cpc7', 'cal_cpc8',
  'cal_cpc9_0', 'cal_cpc9_1', 'cal_cpc9_2', 'cal_cpc9_3', 'cal_cpc9_4', 'cal_cpc9_5', 'cal_cpc9_6', 'cal_cpc9_7', 'cal_cpc9_8',
  'cal_cpc10', 'cal_cpc11', 'cal_cpc12', 'cal_cpc13', 'cal_cpc14', 'cal_cpc15', 'cal_cpc16', 'cal_cpc17',
  'cal_epc1', 'cal_epc2'
];

function generateFakeData(idx: number, len = 100) {
  const base = Array(len).fill(0).map((_, i) => i);
  const hcpos = base.map(i =>
    Math.sin(i / (8 + idx)) * (40 + idx * 2) +
    Math.cos(i / (3 + idx % 5)) * (10 + idx) +
    (Math.random() - 0.5) * 10 * (1 + idx % 3)
  );
  const strippos = base.map(i =>
    Math.cos(i / (7 + idx)) * (30 + idx * 3) +
    Math.sin(i / (2 + idx % 4)) * (15 + idx) +
    (Math.random() - 0.5) * 12 * (1 + (idx + 1) % 4)
  );
  return { hcpos, strippos };
}

const showDetail = async (row: any) => {
  // Assign API data to detailData
  detailData.extid = row.extid;
  detailData.steelGrade = row.steelGrade;
  detailData.width = row.width;
  detailData.thick = row.thick;
  detailData.length = row.length;
  detailData.paopianRate = row.paopianRate;
  detailData.paopianFlagTrue = row.paopianFlagTrue; // 0 or 1
  // Format timestamp in detail view as well
  detailData.createTime = row.time instanceof Date
    ? row.time.toLocaleString()
    : (typeof row.time === 'number'
      ? new Date(row.time).toLocaleString()
      : row.time ?? '-'); // Handle if already string or null/undefined
  detailData.shiftNo = row.shiftNo;
  detailData.gradeCode = row.gradeCode;
  detailData.widthCode = row.widthCode;
  detailData.thickCode = row.thickCode; //出口厚度分档号

  detailData.entryThick = row.entryThick;
  detailData.entryWidth = row.entryWidth;
  detailData.entryLength = row.entryLength; // Assuming API provides this or it's derived
  detailData.hotCoilId = row.hotCoilId;
  detailData.paopianFlag = row.paopianFlag; //纠偏满载

  // For "跑偏原因智能分析" section
  // These are kept as mock or need specific logic if not directly from 'row'
  detailData.isSpecialSteel = row.extid && row.extid.includes('SP') ? true : false; // Example mock logic
  detailData.historyRisk = row.paopianRate !== null ? Math.round(row.paopianRate / 10) : 0; // Example mock logic
  detailData.hotRollCondition = (row.thickCode || 0) > 1 ? '一般' : '良好'; // Example mock logic
  detailData.c40Passrate = row.c40Passrate; //凸度命中率
  detailData.w40Passrate = row.w40Passrate; //楔形命中率

  // 新增：调用主题接口并组装CPC9-0~CPC9-8数据
  const params = {
    line: 'CAL1630',
    extid: row.extid,
    theme_group_id: 'PAOPIAN_RES'
  }
  const themeRes = await ActualPerformanceRollDeviationApi.querytheme(params)
  console.log("的手法首发", themeRes);
  const cpcData: any[] = []
  for (let i = 0; i < cpcChartNames.length; i++) {
    const key = cpcDataKeys[i]
    if (key.startsWith('cal_cpc9_')) {
      // 三条线
      let hcpos1 = themeRes.data.data?.curve[`${key}_1_hcpos`];
      let hcpos2 = themeRes.data.data?.curve[`${key}_2_hcpos`];
      let strippos = themeRes.data.data?.curve[`${key}_strippos`];
      if (!hcpos1 || !hcpos2 || !strippos) {
        const fake = generateFakeData(i, 100);
        hcpos1 = fake.hcpos;
        hcpos2 = fake.hcpos.map(v => v * 0.8);
        strippos = fake.strippos;
      }
      cpcData.push({
        name: cpcChartNames[i],
        x: strippos.map((_: any, idx: number) => idx + 1),
        hcpos1,
        hcpos2,
        strippos
      })
    } else if (key.startsWith('cal_epc')) {
      // epc1/2
      let hcpos = themeRes.data.data?.curve[`${key}_hcpos`];
      let strippos = themeRes.data.data?.curve[`${key}_strippos`];
      if (!hcpos || !strippos) {
        const fake = generateFakeData(i, 100);
        hcpos = fake.hcpos;
        strippos = fake.strippos;
      }
      cpcData.push({
        name: cpcChartNames[i],
        x: hcpos.map((_: any, idx: number) => idx + 1),
        hcpos,
        strippos
      })
    } else {
      // 其它CPC
      let hcpos = themeRes.data.data?.curve[`${key}_hcpos`];
      let strippos = themeRes.data.data?.curve[`${key}_strippos`];
      if (!hcpos || !strippos) {
        const fake = generateFakeData(i, 100);
        hcpos = fake.hcpos;
        strippos = fake.strippos;
      }
      cpcData.push({
        name: cpcChartNames[i],
        x: hcpos.map((_: any, idx: number) => idx + 1),
        hcpos,
        strippos
      })
    }
  }
  detailData.cpcData = cpcData
  detailDialogVisible.value = true;
}

// --- Chart Initialization ---

const initDetailCharts = () => {
  disposeCharts();
  cpcChartInstances = [];
  for (let index = 0; index < cpcChartNames.length; index++) {
    const ref = cpcChartRefs.value[index];
    if (ref && detailData.cpcData[index]) {
      const showXAxisLabel = (cpcChartNames[index] === 'EPC2');
      let cpcOption;
      if (cpcChartNames[index].startsWith('CPC9-')) {
        // 三条线
        cpcOption = {
          tooltip: { trigger: 'axis' },
          grid: { left: '10%', right: '5%', top: '10%', bottom: '15%' },
          xAxis: {
            type: 'category',
            boundaryGap: false,
            data: detailData.cpcData[index].x,
            axisLabel: { fontSize: 10, show: showXAxisLabel }
          },
          yAxis: {
            type: 'value',
            min: -100,
            max: 100,
            axisLabel: { fontSize: 10 }
          },
          series: [
            {
              name: '缸1',
              type: 'line',
              smooth: true,
              symbol: 'none',
              data: detailData.cpcData[index].hcpos1,
              lineStyle: { color: '#5470C6' }
            },
            {
              name: '缸2',
              type: 'line',
              smooth: true,
              symbol: 'none',
              data: detailData.cpcData[index].hcpos2,
              lineStyle: { color: '#91CC75' }
            },
            {
              name: '带钢',
              type: 'line',
              smooth: true,
              symbol: 'none',
              data: detailData.cpcData[index].strippos,
              lineStyle: { color: '#FFD600' }
            }
          ]
        };
      } else {
        // 两条线
        cpcOption = {
          tooltip: { trigger: 'axis' },
          grid: { left: '10%', right: '5%', top: '10%', bottom: '15%' },
          xAxis: {
            type: 'category',
            boundaryGap: false,
            data: detailData.cpcData[index].x,
            axisLabel: { fontSize: 10, show: showXAxisLabel }
          },
          yAxis: {
            type: 'value',
            min: -100,
            max: 100,
            axisLabel: { fontSize: 10 }
          },
          series: [
            {
              name: '纠偏缸位置',
              type: 'line',
              smooth: true,
              symbol: 'none',
              data: detailData.cpcData[index].hcpos,
              lineStyle: { color: '#5470C6' }
            },
            {
              name: '带钢位置',
              type: 'line',
              smooth: true,
              symbol: 'none',
              data: detailData.cpcData[index].strippos,
              lineStyle: { color: '#FFD600' }
            }
          ]
        };
      }
      const chart = echarts.init(ref);
      chart.setOption(cpcOption);
      chart.resize();
      cpcChartInstances.push(chart);
    }
  }
  // Init Convexity/Wedge Chart
  if (convexityWedgeChartRef.value) {
    convexityWedgeChartInstance = echarts.init(convexityWedgeChartRef.value);
    const cwOption: EChartsOption = {
      tooltip: { trigger: 'axis' },
      legend: {
        data: ['凸度曲线-C40', '楔形曲线-W40'],
        bottom: 5,
        textStyle: { fontSize: 10 }
      },
      grid: { left: '10%', right: '8%', top: '10%', bottom: '20%' },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: detailData.convexityWedgeData.x,
        name: '(m)', // X-axis name
        nameLocation: 'end',
        axisLabel: { fontSize: 10 }
      },
      yAxis: {
        type: 'value',
        name: 'μm', // Y-axis name
        axisLabel: { fontSize: 10 }
        // Consider min/max based on data or image
      },
      series: [
        {
          name: '凸度曲线-C40',
          type: 'line',
          smooth: true,
          symbol: 'none',
          data: detailData.convexityWedgeData.c40,
          lineStyle: { color: '#5470C6' },
          markLine: {
            symbol: ['none', 'none'],
            label: { show: true, position: 'end', formatter: '上限' },
            data: [{ yAxis: 50 }], // Example upper limit
            lineStyle: { type: 'dashed', color: '#F56C6C' }
          }
        },
        {
          name: '楔形曲线-W40',
          type: 'line',
          smooth: true,
          symbol: 'none',
          data: detailData.convexityWedgeData.w40,
          lineStyle: { color: '#EE6666' },
          markLine: {
            symbol: ['none', 'none'],
            label: { show: true, position: 'end', formatter: '下限' },
            data: [{ yAxis: -40 }], // Example lower limit
            lineStyle: { type: 'dashed', color: '#F56C6C' }
          }
        }
      ]
    };
    convexityWedgeChartInstance.setOption(cwOption);
  }

  // Init Process Trace Chart
  if (processTraceChartRef.value) {
    processTraceChartInstance = echarts.init(processTraceChartRef.value);
    const ptOption: EChartsOption = {
      tooltip: { trigger: 'axis' },
      legend: {
        data: ['5机张力差', '5机张力差2', '5机出口速度'], // Names adjusted
        bottom: 5,
        textStyle: { fontSize: 10 }
      },
      grid: { left: '10%', right: '15%', top: '10%', bottom: '20%' }, // Adjust right for dual axis
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: detailData.processTraceData.x,
        axisLabel: { fontSize: 10 }
      },
      yAxis: [
        {
          type: 'value',
          name: 'KN', // Y-axis 1 name
          position: 'left',
          axisLabel: { fontSize: 10 }
          // Consider scale based on tension data
        },
        {
          type: 'value',
          name: 'm/min', // Y-axis 2 name
          position: 'right',
          axisLabel: { fontSize: 10 }
          // Consider scale based on speed data
        }
      ],
      series: [
        {
          name: '5机张力差',
          type: 'line',
          yAxisIndex: 0,
          smooth: true,
          symbol: 'none',
          data: detailData.processTraceData.tensionDiff1,
          lineStyle: { color: '#5470C6' }
        },
        {
          name: '5机张力差2', // Added second tension series
          type: 'line',
          yAxisIndex: 0,
          smooth: true,
          symbol: 'none',
          data: detailData.processTraceData.tensionDiff2,
          lineStyle: { color: '#91CC75' }
        },
        {
          name: '5机出口速度',
          type: 'line',
          yAxisIndex: 1,
          smooth: true,
          symbol: 'none',
          data: detailData.processTraceData.speed,
          lineStyle: { color: '#FAC858' }
        }
      ]
    };
    processTraceChartInstance.setOption(ptOption);
  }
}

// --- Chart Cleanup & Resize ---
const disposeCharts = () => {
  cpcChartInstances.forEach(chart => chart?.dispose());
  convexityWedgeChartInstance?.dispose();
  processTraceChartInstance?.dispose();
  cpcChartInstances = [];
  convexityWedgeChartInstance = null;
  processTraceChartInstance = null;
  if (cpcBigChartInstance) {
    cpcBigChartInstance.dispose();
    cpcBigChartInstance = null;
  }
}

const handleDialogClose = () => {
  disposeCharts();
}

const handleResize = () => {
  cpcChartInstances.forEach(chart => chart?.resize());
  convexityWedgeChartInstance?.resize();
  processTraceChartInstance?.resize();
  cpcBigChartInstance?.resize();
}

const handleDialogOpened = () => {
  setTimeout(() => {
    initDetailCharts();
  }, 100);
};

onMounted(() => {
  window.addEventListener('resize', handleResize);
  handleSearch(); // Load initial data
});

onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
  disposeCharts(); // Ensure cleanup on component unmount
});

// 字段label映射
function getFieldLabel(key: string): string {
  if (/^cpc(\d+)Avg$/.test(key)) {
    const idx = Number(key.match(/^cpc(\d+)Avg$/)![1]);
    if (idx < 90) return `CPC${idx}`;
    return `CPC9-${idx - 90}`;
  }
  if (/^cpc(\d+)StripMax$/.test(key)) {
    const idx = Number(key.match(/^cpc(\d+)StripMax$/)![1]);
    if (idx < 90) return `CPC${idx}`;
    return `CPC9-${idx - 90}`;
  }
  if (/^cpc(\d+)StripAvg$/.test(key)) {
    const idx = Number(key.match(/^cpc(\d+)StripAvg$/)![1]);
    if (idx < 90) return `CPC${idx}`;
    return `CPC9-${idx - 90}`;
  }
  const map: Record<string, string> = {
    extid: '出口卷号',
    entid: '入口卷号',
    steelGrade: '钢种',
    width: '宽度',
    thick: '厚度',
    gradeCode: '钢种分档',
    widthCode: '宽度分档',
    thickCode: '厚度分档',
    paopianFlag: '纠偏满载',
    paopianFlagTrue: '是否跑偏',
    createTime: '生产时间',
    shiftNo: '班次',
    entryThick: '入口厚度',
    entryWidth: '入口宽度',
    entryLength: '入口长度',
    hotCoilId: '热卷号',
    paopianRate: '预测跑偏概率',
    c40Passrate: '凸度命中率',
    w40Passrate: '楔形命中率',
    length: '长度',
    // ...可继续补充
  };
  return map[key] || key;
}
// 判断时间字段
function isTimeField(key: string): boolean {
  return key.toLowerCase().includes('time');
}
// 时间格式化
function formatDate(val: any): string {
  if (!val) return '-';
  const date = new Date(Number(val));
  if (isNaN(date.getTime())) return '-';
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  const h = String(date.getHours()).padStart(2, '0');
  const min = String(date.getMinutes()).padStart(2, '0');
  const s = String(date.getSeconds()).padStart(2, '0');
  return `${y}-${m}-${d} ${h}:${min}:${s}`;
}
// 自动提取主表基础字段和CPC相关字段
const baseTableFields = computed(() => {
  if (!tableData.length) return [];
  const allKeys = Object.keys(tableData[0]);
  // 基础字段优先
  const base = ['entid', 'extid', 'steelGrade', 'width', 'thick', 'gradeCode', 'widthCode', 'thickCode', 'paopianFlag', 'paopianFlagTrue', 'createTime', 'shiftNo', 'entryThick', 'entryWidth', 'entryLength', 'hotCoilId', 'paopianRate', 'c40Passrate', 'w40Passrate', 'length'];
  return base.filter(k => allKeys.includes(k));
});
// 详情弹窗基础字段和CPC相关字段
const baseDetailFields = computed(() => {
  const allKeys = Object.keys(detailData);
  const base = [
    'extid', 'entid', 'steelGrade', 'width', 'thick', 'gradeCode', 'widthCode', 'thickCode', 'paopianFlag', 'paopianFlagTrue', 'createTime', 'shiftNo', 'entryThick', 'entryWidth', 'entryLength', 'hotCoilId', 'paopianRate', 'c40Passrate', 'w40Passrate', 'length'
  ];
  return base.filter(k => allKeys.includes(k));
});
// 自动提取主表CPC分组字段
const cpcAvgFields = computed(() => {
  if (!tableData.length) return [];
  return Object.keys(tableData[0]).filter(k => /^cpc(\d+)Avg$/.test(k));
});
const cpcStripAvgFields = computed(() => {
  if (!tableData.length) return [];
  return Object.keys(tableData[0]).filter(k => /^cpc(\d+)StripAvg$/.test(k));
});
const cpcStripMaxFields = computed(() => {
  if (!tableData.length) return [];
  return Object.keys(tableData[0]).filter(k => /^cpc(\d+)StripMax$/.test(k));
});

</script>

<style scoped>
/* ... (之前的样式保持不变) ... */
.aprd-container {
  padding: 15px;
  background-image: linear-gradient(to top, white, #2c69e8) !important;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

.aprd-search-container {
  margin-bottom: 15px;
  padding: 10px 15px;
  background-color: rgba(245, 247, 250, 0.8);
  border-radius: 4px;
  flex-shrink: 0;
}

.aprd-search-form .el-form-item {
  margin-bottom: 8px;
  margin-right: 10px;
}

:deep(.aprd-search-form .el-input--small .el-input__wrapper),
:deep(.aprd-search-form .el-select--small .el-select__wrapper),
:deep(.aprd-search-form .el-date-editor--small.el-input__wrapper) {
  height: 28px;
  line-height: 28px;
}

:deep(.aprd-search-form .el-input--small .el-input__inner),
:deep(.aprd-search-form .el-select--small .el-select__input-wrapper input),
:deep(.aprd-search-form .el-date-editor--small .el-range-input),
:deep(.aprd-search-form .el-date-editor--small .el-range-separator) {
  height: 26px !important;
  line-height: 26px !important;
  font-size: 12px !important;
}

:deep(.aprd-search-form .el-select--small) {
  width: 150px;
}

:deep(.aprd-search-form .el-form-item__label) {
  font-size: 12px;
  line-height: 28px;
  color: #606266;
  padding-right: 8px;
}

.aprd-table-container {
  flex-grow: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* Added border and background for context */
  border: 1px solid #dcdfe6;
  background-color: #fff;
  border-radius: 4px;
}

:deep(.el-table) {
  font-size: 12px;
}

:deep(.el-table th.el-table__cell) {
  padding: 6px 0;
  background-color: #f5f7fa !important;
  /* Lighter header */
  color: #606266 !important;
  font-weight: 500;
}

:deep(.el-table td.el-table__cell) {
  padding: 4px 0;
}

:deep(.el-table .el-table__cell) {
  text-align: center;
}

:deep(.el-table__body tr td.el-table-fixed-column--left),
:deep(.el-table__body tr td.el-table-fixed-column--right) {
  /* Ensure fixed columns have background consistent with row */
  background-color: inherit !important;
}

:deep(.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell) {
  background-color: #ecf5ff !important;
}

:deep(.el-table__body tr.current-row > td.el-table__cell) {
  background-color: #d9ecff !important;
}

.aprd-pagination {
  margin-top: 15px;
  padding: 5px 10px;
  background-color: #fff;
  /* Match table container background */
  border-top: 1px solid #dcdfe6;
  border-radius: 0 0 4px 4px;
  display: flex;
  justify-content: flex-end;
  flex-shrink: 0;
}

/* --- Detail Dialog Styles --- */
:deep(.aprd-detail-dialog .el-dialog__header) {
  background-color: #f5f7fa;
  /* Light header background */
  padding: 10px 20px;
  margin-right: 0;
  border-bottom: 1px solid #e4e7ed;
}

:deep(.aprd-detail-dialog .el-dialog__title) {
  color: #303133;
  /* Darker title color */
  font-size: 16px;
  font-weight: 600;
}

:deep(.aprd-detail-dialog .el-dialog__headerbtn .el-dialog__close) {
  color: #909399;
}

:deep(.aprd-detail-dialog .el-dialog__headerbtn .el-dialog__close:hover) {
  color: #409EFF;
}

:deep(.aprd-detail-dialog .el-dialog__body) {
  padding: 0;
  /* Remove default body padding */
}

.aprd-detail-container {
  padding: 15px;
  max-height: calc(90vh - 50px - 60px);
  /* Viewport height - top offset - header - footer */
  overflow-y: auto;
  background-color: #fff;
  /* Ensure white background inside */
}

.aprd-detail-info {
  margin-bottom: 15px;
}

:deep(.aprd-detail-info .el-descriptions__label) {
  background-color: #f5f7fa;
  font-weight: normal;
  color: #606266;
}

:deep(.aprd-detail-info .el-descriptions__content) {
  color: #303133;
}

.aprd-detail-charts-area {
  display: flex;
  gap: 15px;
  min-height: 450px;
  /* Ensure minimum height for charts */
}

.aprd-cpc-charts-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  /* 卡片之间无间隙 */
  max-height: 700px;
  overflow-y: auto;
  width: 100%;
  min-width: 400px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  background: #fff;
}

.aprd-cpc-chart-item {
  width: 100%;
  min-width: 220px;
  background: transparent;
  border-left: none;
  border-right: none;
  border-top: none;
  border-bottom: 1px solid #e4e7ed;
  border-radius: 0;
  margin-bottom: 0;
  display: flex;
  flex-direction: row;
  /* 横向排列 */
  align-items: center;
}

.aprd-cpc-chart-title {
  font-size: 14px;
  color: #333;
  min-width: 40px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: none;
  border-bottom: none;
  padding: 0;
}

.aprd-cpc-chart {
  height: 120px;
  min-width: 180px;
  flex: 1;
}

.aprd-analysis-charts {
  flex: 1 1 35%;
  min-width: 320px;
  max-width: 420px;
  margin-left: 16px;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.aprd-analysis-section {
  min-height: 150px;
  /* Ensure analysis section has some height */
}

.aprd-analysis-content {
  padding: 10px 15px;
  font-size: 12px;
  color: #606266;
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.aprd-analysis-content .analysis-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Scrollbar styling for detail container */
.aprd-detail-container::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.aprd-detail-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.aprd-detail-container::-webkit-scrollbar-thumb {
  background-color: #c0c4cc;
  border-radius: 3px;
}

.aprd-detail-container::-webkit-scrollbar-thumb:hover {
  background-color: #a8abb2;
}

/* Footer alignment */
.dialog-footer {
  display: flex;
  justify-content: flex-end;
}
</style>
